package novel.manager.web.controller;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import novel.common.pojo.JSONResponse;
import novel.manager.pojo.spider.Chapter;
import novel.manager.pojo.spider.ChapterDetail;
import novel.manager.service.iface.spider.chapter.IChapterDetailSpider;
import novel.manager.service.iface.spider.chapter.IChapterSpider;
import novel.manager.service.iface.web.INovelService;
import novel.manager.service.utils.ChapterDetailSpiderFactory;
import novel.manager.service.utils.ChapterSpiderFactory;
import novel.manager.service.utils.NovelSpiderUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.databind.ObjectMapper;

/**这里用到了novel.spider,奇怪的是novel.spider只依赖了common却可以被没有依赖novel.spider的web调用。
 * 个人理解：manager中的模块可以相互依赖，既然web中用到novel.spider，novel.spider中用到pojo、mapper和数据库连接相关的依赖，
 * 那么直接合并到manager中，使各个模块的src/main/java和src/main/resources都合并到manager中，manager作用一个对外的项目，
 * 若担心代码排版混乱，可以在里面建立各种包，如按功能划分同级（spider,storage,web），按类型划分同级（impl和iface）
 * */
@Controller
public class NovelController {
	/**@Autowired 与@Resource的区别： 
	1、 @Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。
	2、 @Autowired默认按类型装配（这个注解是属业spring的），默认情况下必须要求依赖对象必须存在，如果要允许null值，可以设置它的required属性为false，
		如：@Autowired(required=false) ，如果我们想使用名称装配可以结合@Qualifier注解进行使用，
	 * @Resource（这个注解属于J2EE的），默认安装名称进行装配，名称可以通过name属性进行指定，如果没有指定name属性，当注解写在字段上时，
	 * 默认取字段名进行安装名称查找，如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。
	 * 但是需要注意的是，如果name属性一旦指定，就只会按照名称进行装配。
	 * 推荐使用：@Resource注解在字段上，这样就不用写setter方法了，并且这个注解是属于J2EE的，减少了与spring的耦合。这样代码看起就比较优雅*/
	@Autowired
	private INovelService service;
	//个人认为这个静态代码块没有必要，待验证
	static {
		//jvm加载时执行，只执行一次
		/** 读取小说抓取要素配置文件 */
		NovelSpiderUtil.xml2map("Spider-Rule.xml");
	}
	/**请求抓取章节列表并响应到前端*/
	@RequestMapping(value = "/test/chapters", method = RequestMethod.GET)
	/*转为jquery的json对象响应到前端.
	 * jquery的json对象：Object[Object { id=1003, name="omega养成系统", author="墨李", 更多...}, Object { id=1017, name="Omega拒绝被标记", author="狐生有梦", 更多...}]
	 * javascript的json对象：[Object { id=1003, name="omega养成系统", author="墨李", 更多...}, Object { id=1017, name="Omega拒绝被标记", author="狐生有梦", 更多...}]
	 * 要使用juery就必须使用jquery对象，javacript的json对象b转jquery的json对象a：   var $a=$(b);
	 */
	@ResponseBody
	public JSONResponse getsChapter(String url) {
		IChapterSpider spider = ChapterSpiderFactory.getChapterSpider(url);
		List<Chapter> chapters = spider.getChapters(url);
		//打包响应数据
		return JSONResponse.success(chapters);
	}
	/**请求抓取章节详细内容并响应到前端*/
	@RequestMapping(value = "/test/chapterDetail", method = RequestMethod.GET)
	/*转为jquery的json对象响应到前端.
	 * jquery的json对象：Object[Object { id=1003, name="omega养成系统", author="墨李", 更多...}, Object { id=1017, name="Omega拒绝被标记", author="狐生有梦", 更多...}]
	 * javascript的json对象：[Object { id=1003, name="omega养成系统", author="墨李", 更多...}, Object { id=1017, name="Omega拒绝被标记", author="狐生有梦", 更多...}]
	 * 要使用juery就必须使用jquery对象，javacript的json对象b转jquery的json对象a：   var $a=$(b);
	 */
	@ResponseBody
	public JSONResponse getChapterDetail(String url) {
		IChapterDetailSpider spider = ChapterDetailSpiderFactory.getChapterDetailSpider(url);
		ChapterDetail detail = spider.getChapterDetail(url);
		return JSONResponse.success(detail);
	}
	/**通过关键字查询小说*/
	@RequestMapping(value = "/novelSearch", method = RequestMethod.POST)
	/*转为jquery的json对象响应到前端.
	 * jquery的json对象：Object[Object { id=1003, name="omega养成系统", author="墨李", 更多...}, Object { id=1017, name="Omega拒绝被标记", author="狐生有梦", 更多...}]
	 * javascript的json对象：[Object { id=1003, name="omega养成系统", author="墨李", 更多...}, Object { id=1017, name="Omega拒绝被标记", author="狐生有梦", 更多...}]
	 * 要使用juery就必须使用jquery对象，javacript的json对象b转jquery的json对象a：   var $a=$(b);
	 */
	@ResponseBody
	public JSONResponse getsNovelByKeyword(String keyword) throws UnsupportedEncodingException {
		System.out.println("NovelController.getsNovelByKeyword()");
		
		//解决编码问题：方式1：tomcat默认编码是ISO-8859-1，所以先原样解码再编码
		//keyword=new String(keyword.getBytes("ISO-8859-1"),"UTF-8");
		return JSONResponse.success(service.getsNovelByKeyword(keyword));
	}
	/**通过关键字查询指定平台的小说*/
	@RequestMapping(value = "/novelSearch2", method = RequestMethod.POST)
	/*转为jquery的json对象响应到前端.
	 * jquery的json对象：Object[Object { id=1003, name="omega养成系统", author="墨李", 更多...}, Object { id=1017, name="Omega拒绝被标记", author="狐生有梦", 更多...}]
	 * javascript的json对象：[Object { id=1003, name="omega养成系统", author="墨李", 更多...}, Object { id=1017, name="Omega拒绝被标记", author="狐生有梦", 更多...}]
	 * 要使用juery就必须使用jquery对象，javacript的json对象b转jquery的json对象a：   var $a=$(b);
	 */
	@ResponseBody
	public JSONResponse getsNovelByKeyword(String keyword, int platformId) throws UnsupportedEncodingException {
		//解决编码问题：方式1：tomcat默认编码是ISO-8859-1，所以先原样解码再编码
		//keyword=new String(keyword.getBytes("ISO-8859-1"),"UTF-8");
		return JSONResponse.success(service.getsNovelByKeyword(keyword, platformId));
	}
	/**抓取章节列表并跳转到章节列表页面
	 * @throws Exception */
	@RequestMapping(value = "/chapterList", method = RequestMethod.GET)
	public ModelAndView showChapterList(String url) throws Exception {
		ModelAndView modelAndView = new ModelAndView();
		//view会经过视图解析器
		modelAndView.setViewName("chapterList");
		//设置请求参数
		//抓取到的章节列表
		List<Chapter> listChapter= new ArrayList<Chapter>();
		listChapter=ChapterSpiderFactory.getChapterSpider(url).getChapters(url);
		ObjectMapper mapper = new ObjectMapper();             	          
        //Java集合转JSON字符串  ，到前端要手动转为json对象
		String jsonlist = mapper.writeValueAsString(listChapter); 			
        System.out.println("jsonlist:"+jsonlist); 
        System.out.println("-----------------------------");
        //因为这里要使用请求+参数的方式跳转，且chapters是用来给jquery的each方法调用的，
        //所以要先在java把Java集合转JSON字符串  ，到前端要手动转为javascript的json对象 
		modelAndView.getModel().put("chapters",jsonlist);
		//被抓取的章节列表页面的链接
		modelAndView.getModel().put("baseUrl", url);
		return modelAndView;
	}
	/**抓取章节内容并跳转到章节内容页面*/
	@RequestMapping(value = "/chapterDetail", method = RequestMethod.GET)
	public ModelAndView showChapterDetail(String url, String baseUrl) {
		ModelAndView modelAndView = new ModelAndView();
		//view会经过视图解析器
		modelAndView.setViewName("chapterDetail");
		try {
			//抓取章节内容
			ChapterDetail detail = ChapterDetailSpiderFactory.getChapterDetailSpider(url).getChapterDetail(url);
			//转换换行符
			detail.setContent(detail.getContent().replaceAll("\n", "<br>"));
			//设置请求参数
			//抓取到的章节内容
			modelAndView.getModel().put("chapterDetail", detail);
			//是否抓取成功
			modelAndView.getModel().put("isSuccess", true);
		} catch (Exception e) {
			e.printStackTrace();
			//通知前端：后台出现异常，让前端友好显示
			modelAndView.getModel().put("isSuccess", false);
		}
		modelAndView.getModel().put("baseUrl", baseUrl);
		return modelAndView;
	}
}
